//
//  MediaInfoController.m
//  MediaInfoGUI
//
//  Created by Olivier Larivain on 2/6/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "MediaInfoController.h"
#import "MediaInfoModel.h"
#import "DocumentInfo.h"
#import "MediaInfoList.h"

@interface MediaInfoController()
  -(void) refreshBasicDocument:(DocumentInfo *) documentInfo;
  -(void) refreshTextDocument:(DocumentInfo *) documentInfo;
  -(void) refreshHtmlDocument:(DocumentInfo *) documentInfo;
-(void) refreshAllBasicDocuments;
-(void) refreshAllTextDocuments;
-(void) refreshAllHtmlDocuments;
  -(NSAttributedString *) getVideoStreamInfo:(DocumentInfo *) documentInfo streamId:(NSInteger) id;
  -(NSAttributedString *) getAudioStreamInfo:(DocumentInfo *) documentInfo streamId:(NSInteger) id;
  -(NSAttributedString *) getTextStreamInfo:(DocumentInfo *) documentInfo streamId:(NSInteger) id;

  -(NSAttributedString *) getAttributedStringWithUrl: (NSString *) text url:(NSString*) url;
@end

@implementation MediaInfoController
-(id) init
{
  self = [super init];
  mediaInfoList = [[MediaInfoList alloc] init];
  stringAttributes = [[NSMutableDictionary alloc] init];
  [stringAttributes setObject:[NSFont userFontOfSize:0] forKey:NSFontAttributeName];
  return self;
}

#pragma mark doc manipulation
- (void) loadDocuments:(NSArray *) filenames detailLevel:(DetailLevel) detailLevel
{
  [model clear];
  if([filenames count] == 0)
  {
    return;
  }
  [mediaInfoList close];

  BOOL first = TRUE;
  for(NSString *filename in filenames)
  {
    [self load: filename detailLevel:detailLevel keepPrevious:!first];
    first = FALSE;
  }
}

- (void) loadDocument:(NSString *) filename detailLevel:(DetailLevel) detailLevel keepPrevious:(BOOL) keepPrevious
{
  if(filename == nil)
  {
    return;
  }
  if(!keepPrevious)
  {
    [model clear];
    [mediaInfoList close];
  }
  
  [self load: filename detailLevel: detailLevel keepPrevious: keepPrevious];
}

-(void) load:(NSString *) filename detailLevel:(DetailLevel) detailLevel keepPrevious:(BOOL) keepPrevious
{
  int opened = [mediaInfoList open: filename option: keepPrevious ? None : CloseAll];
  {
    if(opened == 0)
    {
      [mediaInfoList close];
      return;
    }
  }

  for (int i = [model documentCount]; i < opened; i++) 
  {
    DocumentInfo *docInfo = [[DocumentInfo alloc] init];
    [docInfo setName: [mediaInfoList getGeneralInfo: i streamId: 0 parameter: @"FileName"]];
    [docInfo setPath: [mediaInfoList getGeneralInfo: i streamId: 0 parameter: @"CompleteName"]];
    [docInfo setIndex: [model documentCount]];
    
    [model addDocument:docInfo];  
  }
}

#pragma mark document refresh

-(void) refreshDocument:(DocumentInfo *) documentInfo detailLevel:(DetailLevel) detailLevel
{
  switch (detailLevel) 
  {
    case BASIC:
      [self refreshBasicDocument:documentInfo];
      break;
    case TEXT:
      [self refreshTextDocument:documentInfo];
      [model setText: [documentInfo text]];
      break;
    case HTML:
      [self refreshHtmlDocument:documentInfo];
      [model setHtml: [documentInfo html]];
      break;
    default:
      break;
  }
}

- (void) refreshAllDocuments:(DetailLevel) detailLevel
{
  switch(detailLevel)
  {
    case BASIC:
      [self refreshAllBasicDocuments];
      break;
    case TEXT:
          [self refreshAllTextDocuments];
      break;
    case HTML:
          [self refreshAllHtmlDocuments];
      break;
    default:
      break;
}

}

-(NSAttributedString*) getAttributedStringWithUrl: (NSString *) text url:(NSString*) url
{
  NSString *string;
  NSUInteger range;
  if(url == nil || [url isEqual:@""])
  {
    string = [NSString stringWithFormat:@"%@<br/>%@", text, @"No Website Found For This Codec."];
    range = [text length] + [ @"No Website Found For This Codec." length];
  }
  else 
  {
    string = [NSString stringWithFormat:@"%@<br/><a href=\"%@\">%@</a>", text, url, @"Get More Information About This Codec"];  
    range = [text length];
  }
  
  NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithHTML:[string dataUsingEncoding:NSUTF8StringEncoding] documentAttributes: nil];
  [attrString setAttributes:stringAttributes range:NSMakeRange(0, range)];   
  return attrString;
}

-(NSAttributedString *) getVideoStreamInfo:(DocumentInfo *) documentInfo streamId:(NSInteger) id
{
  int index = [documentInfo index];
  NSString *video = [mediaInfoList getVideoInfo: index streamId: id parameter: @"Inform"];
  NSString *videoUrl = [mediaInfoList getVideoInfo: index streamId: id parameter: @"Codec/Url"];
  return [self getAttributedStringWithUrl:video url:videoUrl];
}

-(NSAttributedString *) getAudioStreamInfo:(DocumentInfo *) documentInfo streamId:(NSInteger) id
{
  int index = [documentInfo index];
  NSString *audio = [mediaInfoList getAudioInfo: index streamId: id parameter: @"Inform"];
  NSString *audioUrl = [mediaInfoList getAudioInfo: index streamId: id parameter: @"Codec/Url"];
  return [self getAttributedStringWithUrl:audio url:audioUrl];
}

-(NSAttributedString *) getTextStreamInfo:(DocumentInfo *) documentInfo streamId:(NSInteger) id
{
  int index = [documentInfo index];
  NSString *text = [mediaInfoList getTextInfo: index streamId: id parameter: @"Inform"];
  
  NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithHTML:[text dataUsingEncoding:NSUTF8StringEncoding] documentAttributes: nil];
  [attrString setAttributes:stringAttributes range:NSMakeRange(0, [text length])];   

  return attrString;
}



-(void) refreshBasicDocument:(DocumentInfo *) documentInfo
{
  NSMutableAttributedString *general = [[NSMutableAttributedString alloc] initWithString:@""];
  NSMutableAttributedString *generalMetaData = [[NSMutableAttributedString alloc] initWithString:@""];
  NSAttributedString *video = [[NSAttributedString alloc] initWithString:@""];
  NSAttributedString *audio1 = [[NSAttributedString alloc] initWithString:@""];
  NSAttributedString *audio2 = [[NSAttributedString alloc] initWithString:@""];
  NSAttributedString *text1 = [[NSAttributedString alloc] initWithString:@""];
  NSAttributedString *text2 = [[NSAttributedString alloc] initWithString:@""];
  NSAttributedString *text3 = [[NSAttributedString alloc] initWithString:@""];
  
  int index = [documentInfo index];
  [mediaInfoList setInfoLevel: @"Summary"];
  
  NSMutableString *info = [[NSMutableString alloc] initWithString:[mediaInfoList getGeneralInfo: index streamId: 0 parameter: @"Inform"]];
  NSString *infoMeta = [[NSString alloc] initWithString:[mediaInfoList getGeneralMetaData: index]];


  int nbVideoStream = [mediaInfoList videoStreams: index];
  if(nbVideoStream > 0)
  {
    video = [self getVideoStreamInfo:documentInfo streamId:0];
    [info appendFormat:@"<br/>%d Video Stream%@: ", nbVideoStream, nbVideoStream>1? @"s" :@""];
    [info appendString:[mediaInfoList getVideoCodecInfo: index]];
  }
  
  int nbAudioStream = [mediaInfoList audioStreams: index];
  if(nbAudioStream > 0)
  {
    audio1 = [self getAudioStreamInfo:documentInfo streamId:0];
    [info appendFormat:@"<br/>%d Audio Stream%@: ", nbAudioStream, nbAudioStream>1? @"s" :@""];
    [info appendString:[mediaInfoList getAudioCodecInfo: index]];

    if(nbAudioStream > 1)
    {
      audio2 = [self getAudioStreamInfo:documentInfo streamId:1]; 
    }
  }
  
  int nbTextStream = [mediaInfoList textStreams: index];
  if(nbTextStream > 0)
  {
    [info appendFormat:@"<br/>%d Text Stream%@: ", nbTextStream, nbTextStream>1? @"s" :@""];
    [info appendString:[mediaInfoList getTextCodecInfo: index]];
    text1 = [self getTextStreamInfo:documentInfo streamId:0];
    if(nbTextStream > 1)
    {
      text2 = [self getTextStreamInfo:documentInfo streamId:1];  
    }
    if(nbTextStream > 2)
    {
      text3 = [self getTextStreamInfo:documentInfo streamId:2];
    }
  }
  
  general = [[NSMutableAttributedString alloc] initWithHTML:[info dataUsingEncoding:NSUTF8StringEncoding] documentAttributes: nil];
  [general setAttributes:stringAttributes range:NSMakeRange(0, [general length])];
  
  generalMetaData = [[NSMutableAttributedString alloc] initWithHTML:[infoMeta dataUsingEncoding:NSUTF8StringEncoding] documentAttributes: nil];
  [generalMetaData setAttributes:stringAttributes range:NSMakeRange(0, [generalMetaData length])];

  
  [model setGeneral: general];
  [model setGeneralMetaData:generalMetaData];
  [model setVideo: video];
  [model setAudio1: audio1];
  [model setAudio2: audio2];
  [model setText1: text1];
  [model setText2: text2];
  [model setText3: text3];
}

-(void) refreshTextDocument:(DocumentInfo *) documentInfo
{
  [mediaInfoList setInfoLevel: @"Complete"];
  NSString *global = [mediaInfoList inform: [documentInfo index]];
  [documentInfo setText: global];
}

-(void) refreshHtmlDocument:(DocumentInfo *) documentInfo 
{

  [mediaInfoList setInfoLevel: @"HTML"];    
  NSString *global = [[NSString alloc] initWithFormat:@"<br/>%@", [mediaInfoList inform: [documentInfo index]]];
  [documentInfo setHtml: [[NSAttributedString alloc] initWithHTML:[global dataUsingEncoding: NSUTF8StringEncoding ] documentAttributes:nil]];
}

-(void) refreshAllBasicDocuments
{
    // TODO implement
}
-(void) refreshAllTextDocuments
{
  for(DocumentInfo *docInfo in [model documentInfos])
  {
    [self refreshTextDocument: docInfo];
  }
  
  NSMutableString *text = [[NSMutableString alloc] init];
  for(DocumentInfo *docInfo in [model documentInfos])
  {
    [text appendFormat:@"%@\n\n", [docInfo text]];
  }
  [model setText: text];
}

-(void) refreshAllHtmlDocuments
{
  for(DocumentInfo *docInfo in [model documentInfos])
  {
    [self refreshHtmlDocument: docInfo];
  }
  
  NSMutableAttributedString *htmlContent = [[NSMutableAttributedString alloc] init];
  for(DocumentInfo *docInfo in [model documentInfos])
  {
    [htmlContent appendAttributedString:[docInfo html]];
  }
  [model setHtml: htmlContent];
}

@end
